package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.common.execption.TingShuException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private TrackStatMapper trackStatMapper;

	@Autowired
	private VodService vodService;

	@Autowired
	private UserFeignClient userFeignClient;

	@Autowired
	private RedisTemplate redisTemplate;

    @Autowired
    private AlbumStatMapper albumStatMapper;

	@Autowired
	private AlbumFeignClient albumFeignClient;


	@Override
	@Transactional(rollbackFor = Exception.class)
	public void savaTrackInfo(TrackInfoVo trackInfoVo,Long userId) {
		//TODO 用户id
		userId = 1L;
		TrackInfo trackInfo = BeanUtil.toBean(trackInfoVo, TrackInfo.class);
		trackInfo.setUserId(userId);
		trackInfo.setSource("1");
		trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
		trackInfo.setOrderNum(albumInfo.getIncludeTrackCount() + 1);
		TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
		if(trackMediaInfo != null){
			trackInfo.setMediaDuration(new BigDecimal(trackMediaInfo.getDuration()));
			trackInfo.setMediaSize(trackMediaInfo.getSize());
			trackInfo.setMediaType(trackMediaInfo.getType());
		}
		this.save(trackInfo);
		//保存声音统计信息
		List<String> trackStatCollect = List.of(SystemConstant.TRACK_STAT_COLLECT, SystemConstant.TRACK_STAT_PLAY, SystemConstant.TRACK_STAT_PRAISE, SystemConstant.TRACK_STAT_COMMENT);
		trackStatCollect.stream().forEach(value -> {
			TrackStat trackStat = new TrackStat();
			trackStat.setTrackId(trackInfo.getId());
			trackStat.setStatType(value);
			trackStat.setStatNum(0);
			trackStatMapper.insert(trackStat);
		});
		//更改专辑原来的声音数
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
		albumInfoMapper.updateById(albumInfo);
	}

	@Override
	public Page<TrackListVo> getUserTrackByPage(Page<TrackListVo> pageInfo, TrackInfoQuery trackInfoQuery) {
		return baseMapper.getUserTrackByPage(pageInfo,trackInfoQuery);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
		TrackInfo trackInfo = this.getById(id);
		//原来的视频文件id标识
		String mediaFileIdBefore = trackInfo.getMediaFileId();
		//新的视频文件id标识
		String mediaFileIdAfter = trackInfoVo.getMediaFileId();
		if(!mediaFileIdAfter.equals(mediaFileIdBefore)){
			//获取新的视频文件
			TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(mediaFileIdAfter);
			if(trackMediaInfo != null){
				trackInfo.setMediaDuration(new BigDecimal(trackMediaInfo.getDuration()));
				trackInfo.setMediaSize(trackMediaInfo.getSize());
				trackInfo.setMediaType(trackMediaInfo.getType());
				//删除原来的视频
				vodService.deleteTrackMedia(mediaFileIdBefore);
			}
		}
		BeanUtil.copyProperties(trackInfoVo,trackInfo);
		this.updateById(trackInfo);
	}

	@Override
	public Page<AlbumTrackListVo> findAlbumTrackPage(Page pageInfo, Long albumId, Long userId) {
		Page<AlbumTrackListVo> albumTrackPage = trackInfoMapper.findAlbumTrackPage(pageInfo, albumId, userId);
		AlbumInfo albumInfo = albumInfoMapper.selectOne(new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getId, albumId));
		if(albumInfo == null){
			throw new TingShuException(400,"专辑信息不存在");
		}
		String payType = albumInfo.getPayType();
		Integer tracksForFree = albumInfo.getTracksForFree();
		List<AlbumTrackListVo> records = albumTrackPage.getRecords();
		if(!CollectionUtils.isEmpty(records)){
			if(userId == null){
				//该专辑不是免费
				if(!payType.equals(SystemConstant.ALBUM_PAY_TYPE_FREE)){
					//过滤掉免费集数
					handleShowPaidMark(records,tracksForFree);
				}
			}else{
				Result<UserInfoVo> userInfoVoResult = userFeignClient.getUserInfoVoById(userId);
				Assert.notNull(userInfoVoResult,"用户信息不存在");
				UserInfoVo userInfoVo = userInfoVoResult.getData();
				boolean isCheckNeedStatus = false;
				if(payType.equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE)){
					if(userInfoVo.getIsVip() == 0 || (userInfoVo.getIsVip() == 1 && userInfoVo.getVipExpireTime().before(new Date()))){
						isCheckNeedStatus = true;
					}
				}
				if(payType.equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)){
						isCheckNeedStatus = true;
				}
				if(isCheckNeedStatus){
					List<Long> trackIds = records.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
					Result<Map<String, Integer>> userIsPaidTrackResult = userFeignClient.getUserIsPaidTrack(userId, albumId, trackIds);
					Assert.notNull(userIsPaidTrackResult,"用户购买声音信息不存在");
					Map<String, Integer> map = userIsPaidTrackResult.getData();
					List<AlbumTrackListVo> albumTrackListVos = records.stream().filter(item -> item.getOrderNum() > tracksForFree).collect(Collectors.toList());
					for (AlbumTrackListVo albumTrackListVo : albumTrackListVos) {
						Integer need = map.get(albumTrackListVo.getTrackId().toString());
						if(need == 0){
							albumTrackListVo.setIsShowPaidMark(true);
						}
					}
				}
			}
		}
		return albumTrackPage;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateAlbumStat(TrackStatMqVo trackStatMqVo) {
		//获取唯一标识号
		String businessNo = trackStatMqVo.getBusinessNo();
		//存入redis。防止重复提交
		String key = "businessNo:" + businessNo;
		Boolean b = redisTemplate.opsForValue().setIfAbsent(key, businessNo, 1, TimeUnit.HOURS);
		if(!b){
			return;
		}
		//更新声音统计
		trackStatMapper.updateTrackStat(trackStatMqVo.getTrackId(),trackStatMqVo.getCount(),trackStatMqVo.getStatType());
		String albumType = "";
		if(trackStatMqVo.getStatType().equals(SystemConstant.TRACK_STAT_PLAY)){
			albumType = SystemConstant.ALBUM_STAT_PLAY;
		}
		if(trackStatMqVo.getStatType().equals(SystemConstant.TRACK_STAT_COMMENT)){
			albumType = SystemConstant.ALBUM_STAT_COMMENT;
		}
		//更新专辑统计
		albumStatMapper.updateAlbumStat(trackStatMqVo.getAlbumId(),trackStatMqVo.getCount(),albumType);
	}

	@Override
	public TrackStatVo getTrackStatVo(Long trackId) {
		return baseMapper.getTrackStatVo(trackId);
	}


	private void handleShowPaidMark(List<AlbumTrackListVo> records,Integer tracksForFree) {
		List<AlbumTrackListVo> albumTrackListVos = records.stream().filter(item -> item.getOrderNum() > tracksForFree).collect(Collectors.toList());
		for (AlbumTrackListVo albumTrackListVo : albumTrackListVos) {
			albumTrackListVo.setIsShowPaidMark(true);
		}
	}


	/**
	 * 获取用户需要支付的声音列表
	 * @param userId
	 * @param trackId
	 * @return
	 */
	@Override
	public List<Map<String, Object>> getUserWaitBuyTrackPayList(Long userId, Long trackId) {
		TrackInfo trackInfo = this.getById(trackId);
		Long albumId = trackInfo.getAlbumId();
		//获取该声音之后的声音列表
		List<TrackInfo> waitBuyTrackPayList = this.lambdaQuery()
				.eq(TrackInfo::getAlbumId, albumId)
				.ge(TrackInfo::getOrderNum, trackInfo.getOrderNum())
				.eq(TrackInfo::getIsDeleted, 0)
				.list();
		if(CollectionUtils.isEmpty(waitBuyTrackPayList)){
			throw new TingShuException(404,"没有可以购买的声音");
		}
		//获取用户已购买的声音列表
		List<Long> userPaidIdList;
		if(userId != null){
			Result<List<Long>> userPaidTrackIdListResult = userFeignClient.getUserPaidTrackIdList(albumId);
			Assert.notNull(userPaidTrackIdListResult,"获取用户已购买的声音列表失败，声音为" + trackId);
			userPaidIdList= userPaidTrackIdListResult.getData();
		} else {
            userPaidIdList = Lists.newArrayList();
        }
        //过滤
		if(!CollectionUtils.isEmpty(userPaidIdList)){
			waitBuyTrackPayList = waitBuyTrackPayList.stream().filter(item->!userPaidIdList.contains(item.getId())).collect(Collectors.toList());
		}
		if(CollectionUtils.isEmpty(waitBuyTrackPayList)){
			throw new TingShuException(404,"没有可以购买的声音");
		}
		int count = waitBuyTrackPayList.size();
		List<Map<String,Object>> list = Lists.newArrayList();
		Result<AlbumInfo> albumInfoResult = albumFeignClient.getAlbumInfo(albumId);
		Assert.notNull(albumInfoResult,"获取专辑信息失败，专辑id为：" + albumId);
		AlbumInfo albumInfo = albumInfoResult.getData();
		//价格
		BigDecimal price = albumInfo.getPrice();
		Map<String, Object> currMap = new HashMap<>();
		currMap.put("name", "本集");
		currMap.put("price", price);
		currMap.put("trackCount", 1);
		list.add(currMap);
		for(int i = 10 ; i <= 50 ; i += 10){
			Map<String,Object> map = new HashMap<>();
			if(i <= 50 && i < count){
				map.put("name", "后" + i + "集");
				map.put("price", price.multiply(new BigDecimal(i)));
				map.put("trackCount", i);
				list.add(map);
			}else{
				map.put("name", "后" + count + "集");
				map.put("price", price.multiply(new BigDecimal(count)));
				map.put("trackCount", count);
				list.add(map);
				break;
			}
		}
		return list;
	}

	@Override
	public List<TrackInfo> getWaitBuyTrackInfoList(Long userId, Long trackId, int trackCount) {
		TrackInfo trackInfo = this.getById(trackId);
		Long albumId = trackInfo.getAlbumId();
		//获取该声音之后的声音列表
		LambdaQueryWrapper<TrackInfo> lqw = new LambdaQueryWrapper<>();
		lqw.eq(TrackInfo::getAlbumId,albumId);
		lqw.ge(TrackInfo::getOrderNum,trackInfo.getOrderNum());
		lqw.orderByAsc(TrackInfo::getOrderNum);

		//去掉用户已购买的声音
		Result<List<Long>> userPaidTrackIdListResult = userFeignClient.getUserPaidTrackIdList(albumId);
		Assert.notNull(userPaidTrackIdListResult,"获取用户已购买的声音列表失败，声音为" + trackId);
		List<Long> userPaidIdList= userPaidTrackIdListResult.getData();
		if(!CollectionUtils.isEmpty(userPaidIdList)){
			lqw.notIn(TrackInfo::getId,userPaidIdList);
		}
		//限制
		lqw.last("limit " + trackCount);
		List<TrackInfo> list = this.list(lqw);
		if(CollectionUtils.isEmpty(list)){
			throw new TingShuException(404,"可以购买的声音信息不存在");
		}
		return list;
	}
}
